package com.nullpointer.xchatfinal.utils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.RejectedExecutionException;

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.SeekBar;

import com.facebook.Session;
import com.nullpointer.xchatfinal.object.User;
import com.nullpointer.xchatfinal.object.UserInfo;
import com.nullpointer.xchatfinal.object.UserInfo.GenderType;
import com.quickblox.core.QBEntityCallbackImpl;
import com.quickblox.core.request.QBRequestGetBuilder;
import com.quickblox.core.request.QBRequestUpdateBuilder;
import com.quickblox.customobjects.QBCustomObjects;
import com.quickblox.customobjects.model.QBCustomObject;
import com.quickblox.customobjects.model.QBPermissions;
import com.quickblox.customobjects.model.QBPermissionsLevel;
import com.quickblox.users.model.QBUser;

public class Utils {

	public static void hideKeyboard(Context context, EditText editText) {
		InputMethodManager imm = (InputMethodManager) context
				.getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
	}

	public static void showKeyboard(Context context, EditText editText) {
		InputMethodManager imm = (InputMethodManager) context
				.getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
	}

	public static boolean isConnectingToInternet(Context context) {
		ConnectivityManager connectivity = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		if (connectivity != null) {
			NetworkInfo[] info = connectivity.getAllNetworkInfo();
			if (info != null)
				for (int i = 0; i < info.length; i++)
					if (info[i].getState() == NetworkInfo.State.CONNECTED) {
						return true;
					}

		}
		return false;
	}

	@SuppressLint("NewApi")
	public static <T> void execute(AsyncTask<T, ?, ?> asyncTask, T... params) {
		try {
			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
				asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
						params);
			} else {
				asyncTask.execute(params);
			}
		} catch (RejectedExecutionException e) {
			e.printStackTrace();
		}

	}

	private static HttpClient client = null;

	public static HttpClient getClient() {
		if (client == null) {
			HttpParams params = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(params, 10000);
			client = new DefaultHttpClient(params);
		}
		return client;
	}

	@SuppressLint("NewApi")
	public static void copyTextToClipboard(Context context, String content) {
		int sdk = android.os.Build.VERSION.SDK_INT;
		if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
			android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context
					.getSystemService(Context.CLIPBOARD_SERVICE);
			clipboard.setText(content);
		} else {
			android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context
					.getSystemService(Context.CLIPBOARD_SERVICE);
			android.content.ClipData clip = android.content.ClipData
					.newPlainText("message", content);
			clipboard.setPrimaryClip(clip);
		}
	}

	public static UserInfo getUserInfoFromQBWebsite(String website) {
		String info = website.replace("http://", "");
		UserInfo user;
		try {
			user = UserInfo.fromJsonToUserInfo(info);
		} catch (Exception e) {
			user = new UserInfo();
		}
		return user;
	}

	public static void reportUser(final Integer userID) {
		QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder();
		requestBuilder.setPagesLimit(1);
		requestBuilder.eq(Common.ReportObject.USER_ID_FIELD, userID);

		QBCustomObjects.getObjects(Common.ReportObject.REPORT_CLASS,
				requestBuilder,
				new QBEntityCallbackImpl<ArrayList<QBCustomObject>>() {

					@Override
					public void onSuccess(
							ArrayList<QBCustomObject> customObjects,
							Bundle params) {
						KiraGameLog.d(">>> custom objects: " + customObjects);
						if (customObjects.size() == 0) {
							QBCustomObject newRecord = new QBCustomObject(
									Common.ReportObject.REPORT_CLASS);
							newRecord.put(Common.ReportObject.USER_ID_FIELD,
									userID);
							newRecord.put(Common.ReportObject.NUM_FIELD, 1);
							QBPermissions permissions = new QBPermissions();
							permissions
									.setDeletePermission(QBPermissionsLevel.OPEN);
							permissions
									.setReadPermission(QBPermissionsLevel.OPEN);
							permissions
									.setUpdatePermission(QBPermissionsLevel.OPEN);
							newRecord.setPermission(permissions);
							QBCustomObjects.createObject(newRecord,
									new QBEntityCallbackImpl<QBCustomObject>() {
										@Override
										public void onSuccess(
												QBCustomObject object,
												Bundle params) {
											KiraGameLog
													.d(">>> created object: "
															+ object);
										}

										@Override
										public void onError(List<String> errors) {
											KiraGameLog
													.d("create getReportUser error "
															+ errors);
										}
									});
						} else {
							QBCustomObject object = customObjects.get(0);
							int num = Integer.parseInt(object.getFields()
									.get(Common.ReportObject.NUM_FIELD)
									.toString());
							object.put(Common.ReportObject.NUM_FIELD, num + 1);
							QBCustomObjects.updateObject(object,
									(QBRequestUpdateBuilder) null,
									new QBEntityCallbackImpl<QBCustomObject>() {
										@Override
										public void onSuccess(
												QBCustomObject object,
												Bundle params) {
											KiraGameLog
													.d(">>> updated record: : "
															+ object.toString());
										}

										@Override
										public void onError(List<String> errors) {
											KiraGameLog
													.d("update getReportUser error "
															+ errors);
										}
									});
						}

					}

					@Override
					public void onError(List<String> errors) {
						KiraGameLog.d("getReportUser error " + errors);
					}
				});

	}

	public static void addFriend(final String newFriendID,
			final Integer currentUserID) {
		if (newFriendID.equals(Integer.toString(currentUserID))) {
			return;
		}
		QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder();
		requestBuilder.setPagesLimit(1);
		requestBuilder.eq(Common.FriendsObject.USER_ID, currentUserID);

		QBCustomObjects.getObjects(Common.FriendsObject.FRIENDS_CLASS,
				requestBuilder,
				new QBEntityCallbackImpl<ArrayList<QBCustomObject>>() {

					@Override
					public void onSuccess(
							ArrayList<QBCustomObject> customObjects,
							Bundle params) {
						KiraGameLog.d(">>> custom objects: " + customObjects);
						if (customObjects.size() == 0) {
							QBCustomObject newRecord = new QBCustomObject(
									Common.FriendsObject.FRIENDS_CLASS);
							HashMap<String, Object> fields = new HashMap<String, Object>();
							fields.put(Common.FriendsObject.USER_ID,
									currentUserID);
							fields.put(Common.FriendsObject.LIST_FRIENDS,
									newFriendID);
							newRecord.setFields(fields);
							QBPermissions permissions = new QBPermissions();
							permissions
									.setDeletePermission(QBPermissionsLevel.OPEN);
							permissions
									.setReadPermission(QBPermissionsLevel.OPEN);
							permissions
									.setUpdatePermission(QBPermissionsLevel.OPEN);
							newRecord.setPermission(permissions);
							QBCustomObjects.createObject(newRecord,
									new QBEntityCallbackImpl<QBCustomObject>() {
										@Override
										public void onSuccess(
												QBCustomObject object,
												Bundle params) {
											KiraGameLog
													.d(">>> created object: "
															+ object);
										}

										@Override
										public void onError(List<String> errors) {
											KiraGameLog
													.d("create getReportUser error "
															+ errors);
										}
									});
						} else {
							String friends = null;
							QBCustomObject object = customObjects.get(0);
							Object frObject = object.getFields().get(
									Common.FriendsObject.LIST_FRIENDS);
							if (frObject == null) {
								friends = newFriendID;
							} else {
								friends = frObject.toString();
								if (friends != null) {
									String[] array = friends.split("/");
									Set<String> list = new HashSet<>();
									Collections.addAll(list, array);
									if (!list.contains(newFriendID)) {
										friends = friends + "/" + newFriendID;
									} else {
										return;
									}
								} else {
									friends = newFriendID;
								}
							}

							HashMap<String, Object> fields = new HashMap<String, Object>();
							fields.put(Common.FriendsObject.LIST_FRIENDS,
									friends);
							object.setFields(fields);
							QBCustomObjects.updateObject(object,
									(QBRequestUpdateBuilder) null,
									new QBEntityCallbackImpl<QBCustomObject>() {
										@Override
										public void onSuccess(
												QBCustomObject object,
												Bundle params) {
											KiraGameLog
													.d(">>> updated record: : "
															+ object.toString());
										}

										@Override
										public void onError(List<String> errors) {
											KiraGameLog
													.d("update getReportUser error "
															+ errors);
										}
									});
						}

					}

					@Override
					public void onError(List<String> errors) {
						KiraGameLog.d("getReportUser error " + errors);
					}
				});
	}

	public static void reportGroup(String roomJID) {
		final String groupID = Utils.getDialogIdFromJID(roomJID);
		QBRequestGetBuilder requestBuilder = new QBRequestGetBuilder();
		requestBuilder.setPagesLimit(1);
		requestBuilder.eq(Common.ReportGroupObject.GROUP_ID_FIELD, groupID);

		QBCustomObjects.getObjects(Common.ReportGroupObject.REPORT_GROUP_CLASS,
				requestBuilder,
				new QBEntityCallbackImpl<ArrayList<QBCustomObject>>() {

					@Override
					public void onSuccess(
							ArrayList<QBCustomObject> customObjects,
							Bundle params) {
						KiraGameLog.d(">>> custom objects: " + customObjects);
						if (customObjects.size() == 0) {
							QBCustomObject newRecord = new QBCustomObject(
									Common.ReportGroupObject.REPORT_GROUP_CLASS);
							newRecord.put(
									Common.ReportGroupObject.GROUP_ID_FIELD,
									groupID);
							newRecord
									.put(Common.ReportGroupObject.NUM_FIELD, 1);
							QBPermissions permissions = new QBPermissions();
							permissions
									.setDeletePermission(QBPermissionsLevel.OPEN);
							permissions
									.setReadPermission(QBPermissionsLevel.OPEN);
							permissions
									.setUpdatePermission(QBPermissionsLevel.OPEN);
							newRecord.setPermission(permissions);
							QBCustomObjects.createObject(newRecord,
									new QBEntityCallbackImpl<QBCustomObject>() {
										@Override
										public void onSuccess(
												QBCustomObject object,
												Bundle params) {
											KiraGameLog
													.d(">>> created object: "
															+ object);
										}

										@Override
										public void onError(List<String> errors) {
											KiraGameLog
													.d("create getReportUser error "
															+ errors);
										}
									});
						} else {
							QBCustomObject object = customObjects.get(0);
							int num = Integer.parseInt(object.getFields()
									.get(Common.ReportGroupObject.NUM_FIELD)
									.toString());
							object.put(Common.ReportGroupObject.NUM_FIELD,
									num + 1);
							QBCustomObjects.updateObject(object,
									(QBRequestUpdateBuilder) null,
									new QBEntityCallbackImpl<QBCustomObject>() {
										@Override
										public void onSuccess(
												QBCustomObject object,
												Bundle params) {
											KiraGameLog
													.d(">>> updated record: : "
															+ object.toString());
										}

										@Override
										public void onError(List<String> errors) {
											KiraGameLog
													.d("update getReportUser error "
															+ errors);
										}
									});
						}

					}

					@Override
					public void onError(List<String> errors) {
						KiraGameLog.d("getReportUser error " + errors);
					}
				});

	}

	public static boolean isOnline(QBUser user) {
		long currentTime = System.currentTimeMillis();
		long userLastRequestAtTime = user.getLastRequestAt().getTime();

		// if user didn't do anything last 5 minutes (5*60*1000 milliseconds)
		if ((currentTime - userLastRequestAtTime) > 5 * 60 * 1000) {
			return false;
		}
		return true;
	}
	
	public static String parseDiffTimeToString(long diff) {
		long seconds = diff / 1000;
		long minutes = seconds / 60;
		long hours = minutes / 60;
		long days = hours / 24;

		String friendly = "";
		long num = 0;
		if (days > 0) {
			num = days;
			friendly = days + " day";

		} else if (hours > 0) {
			num = hours;
			friendly = hours + " hour";
		} else if (minutes > 0) {
			num = minutes;
			friendly = minutes + " minute";
		} else {
			num = seconds;
			if(num < 0)
				seconds = 0;
			friendly = seconds + " second";
		}

		if (num > 1) {
			friendly += "s";
		}
		return friendly + " ago";
	}

	public static boolean checkBadword(String input) {
		input = input.toLowerCase(Locale.US);
		for (String word : Common.badWord) {
			if (input.contains(word)) {
				return true;
			}
		}
		return false;
	}

	public static User convertQBUserToUser(QBUser user) {
		User xchatUser = new User();
		xchatUser.setUserID(user.getId());
		xchatUser.setName(user.getFullName());
		UserInfo userInfo;
		if (user.getCustomData() != null) {
			try {
				userInfo = UserInfo.fromJsonToUserInfo(user.getCustomData());
			} catch (Exception e) {
				userInfo = new UserInfo();
			}

		} else {
			userInfo = Utils.getUserInfoFromQBWebsite(user.getWebsite());
		}
		xchatUser.setUserInfo(userInfo);
		return xchatUser;

	}

	public static String getDialogIdFromJID(String roomJID) {
		String dialogID = roomJID.split("_")[1];
		return dialogID.split("@")[0];
	}

	public static long convertDateToLongTime(int year, int month, int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month, day);
		return calendar.getTimeInMillis();
	}

	public static String getSmallAvatarFacebook(String avatarID) {
		if (avatarID == null) {
			return null;
		}
		String[] result = avatarID.split("-");
		String facebookID = result[0];
		String plusURL = "0";
		if (result.length > 1) {
			plusURL = result[1];
		}
		return "https://graph.facebook.com/" + facebookID
				+ "/picture?type=large&t=" + plusURL;
	}

	public static String getLargeAvatarFacebook(String avatarID) {
		if (avatarID == null) {
			return null;
		}
		String[] result = avatarID.split("-");
		String facebookID = result[0];
		String plusURL = "0";
		if (result.length > 1) {
			plusURL = result[1];
		}
		return "https://graph.facebook.com/" + facebookID
				+ "/picture?type=large&t=" + plusURL;
	}

	public static String getAvatarIDFromFacebookID(String facebookID) {
		if (facebookID == null) {
			return null;
		}
		return facebookID + "-" + System.currentTimeMillis();
	}

	public static void callFacebookLogout(Context context) {
		Session session = Session.getActiveSession();
		if (session != null) {

			if (!session.isClosed()) {
				session.closeAndClearTokenInformation();
				// clear your preferences if saved
				DataManager.getInstance(context).setIsLoginWithFB(false);
			}
		} else {

			session = new Session(context);
			Session.setActiveSession(session);

			session.closeAndClearTokenInformation();
			// clear your preferences if saved
			DataManager.getInstance(context).setIsLoginWithFB(false);
		}

	}

	public static boolean isFacebookLoggedIn() {
		Session session = Session.getActiveSession();
		return (session != null && session.isOpened());
	}
}
